#!/bin/sh

# Part of Zombie Navigator
# Copyright © 2016  Zombie Navigator Developers

# Encoding: UTF-8
# JsDoc-ish with shell scripting

# ported from PHP
htmlspecialchars () {
	sed 's/&/\&amp;/g ; s/</\&lt;/g ; s/>/\&gt;/g ; s/"/\&quot;/g'
}

print () {
	printf %s "$1"
}

htmlspecialchars_args () {
	print "$1" | htmlspecialchars
}

# Feed escaped codes, please
indentedCode () {
	sed 's|^	\(.*\)$|<code>\1</code>| ; s|^\s\s\(.*\)$|<code>\1</code>|'
}

removeComments () {
	grep -v '^#'
}

formatPropNames () {
	sed 's/->/→/g ; s/-&gt;/→/g ; s|\(:.*\)$|<span class="type">\1</span>|'
}

genDocs () {
	dir=$1
	title=$2
	footer=$3
	[ -d "$dir" ] || return 1
	cat <<HTML | tr -d '\n'
<!doctype html><meta charset="utf-8"/><title>`htmlspecialchars_args "$title"`</title><style>
HTML
	# CSS embedded in HTML (with some caveats)
	cat <<EMBEDCSS | egrep -v "^\s*$" | tr -d "\t\n" | sed "s/\s\{1,\}/ /g ; s/\s*\([{:>+,;]\)\s*/\1/g ; s/;}/}/g"
:root {
	font-family: sans-serif;
	font-size: 1rem;
	padding: 1rem 2rem;
}
:root > * {
	margin: 0;
}
::-moz-selection {
	background-color: aquamarine;
	color: maroon;
}
footer {
	color: #aaa;
}
section {
	padding-left: 1.5rem;
}
section > :first-child {
	padding-left: .5rem !important;
	border-left: .25rem solid #fcf;
	margin-left: -.75rem;
}
section > section > :first-child {
	border-color: #fea;
}
pre, code {
	font-size: 1rem;
}
pre {
	margin: .5em 0 1em;
}
code {
	background-color: #eff;
	padding: 0 .5em;
}
.usage {
	border-left: solid .25em #cdc;
	padding: 0 1em;
}
.type {
	color: #f6e;
}
p {
	white-space: pre-wrap;
}
dt {
	font-family: monospace;
	font-size: 1rem;
	padding: .25em .2em;
	background-color: #eee;
}
dd {
	white-space: pre-wrap;
	margin: .2em 0 1.5em 2em;
}
h1 {
	font-size: 2.75rem;
	font-weight: 200;
}
h2 {
	font-size: 2rem;
	font-weight: normal;
}
h3 {
	font-size: 1.6rem;
}
h4 {
	font-size: 1.25rem;
}
h5 {
	font-size: 1.1rem;
}
EMBEDCSS
	cat <<HTML | tr -d '\n'
</style><h1>`htmlspecialchars_args "$title"`</h1>
HTML
	
	[ -f "$dir/README" ] && {
		print "<p>"
		cat "$dir/README" | htmlspecialchars
		print "</p>"
	}
	[ -f "$dir/COPYING" ] && {
		print "<h2>License</h2><pre>"
		cat "$dir/COPYING" | htmlspecialchars
		print "</pre>"
	}
	[ -f "$dir/usage" ] && {
		print '<h2>Usage</h2><p class="usage">'
		cat "$dir/usage" | htmlspecialchars | removeComments | indentedCode
		print "</p>"
	}
	
	print "<h2>Modules</h2>"
	for module in `cd "$dir" ; find . -type d | sort` ; do
		moduleDesc="$dir/$module/module-desc"
		[ -f "$moduleDesc" ] || continue
		moduleName=`print "$module" | sed 's,^\./,,'`
		print "<section>"
		print "<h3>Module: `htmlspecialchars_args "$moduleName"`</h3>"
		print "<p>"
		cat "$moduleDesc" | htmlspecialchars
		print "</p>"
		
		[ -f "$dir/$module/usage" ] && {
			print '<h4>Usage</h4><pre class="usage">'
			cat "$dir/$module/usage" | htmlspecialchars | removeComments
			print "</pre>"
		}
		
		print "<h4>Properties</h4><dl>"
		for propertyPath in "$dir/$module"/property-* ; do
			[ -f "$propertyPath" ] || continue
			property=${propertyPath##*-}
			print "<dt>"
			head -n 1 "$propertyPath" | htmlspecialchars | formatPropNames
			print "</dt><dd>"
			tail -n +2 "$propertyPath" | htmlspecialchars | removeComments | indentedCode
			print "</dd>"
		done
		print "</dl>"
		
		print "<h4>Methods</h4><dl>"
		for methodPath in "$dir/$module"/method-* ; do
			[ -f "$methodPath" ] || continue
			method=${methodPath##*-}
			print "<dt>"
			head -n 1 "$methodPath" | htmlspecialchars | formatPropNames
			print "</dt><dd>"
			tail -n +2 "$methodPath" | htmlspecialchars | removeComments | indentedCode
			print "</dd>"
		done
		print "</dl>"
		
		for ifacePath in "$dir/$module"/interface-* ; do
			[ -d "$ifacePath" ] || continue
			iface=${ifacePath##*-}
			print '<section>'
			print "<h4>`htmlspecialchars_args "Interface: $moduleName~$iface"`</h4>"
			[ -f "$ifacePath/interface-desc" ] && {
				print "<p>"
				cat "$ifacePath/interface-desc" | htmlspecialchars
				print "</p>"
			}
			
			[ -f "$ifacePath/usage" ] && {
				print '<h5>Usage</h5><pre class="usage">'
				cat "$ifacePath/usage" | htmlspecialchars | removeComments
				print "</pre>"
			}
			
			print "<h5>Properties</h5><dl>"
			for propertyPath in "$ifacePath"/property-* ; do
				[ -f "$propertyPath" ] || continue
				property=${propertyPath##*-}
				print "<dt>"
				head -n 1 "$propertyPath" | htmlspecialchars | formatPropNames
				print "</dt><dd>"
				tail -n +2 "$propertyPath" | htmlspecialchars | removeComments | indentedCode
				print "</dd>"
			done
			print "</dl>"
			
			print "<h5>Methods</h5><dl>"
			for methodPath in "$ifacePath"/method-* ; do
				[ -f "$methodPath" ] || continue
				method=${methodPath##*-}
				print "<dt>"
				head -n 1 "$methodPath" | htmlspecialchars | formatPropNames
				print "</dt><dd>"
				tail -n +2 "$methodPath" | htmlspecialchars | removeComments | indentedCode
				print "</dd>"
			done
			print "</dl>"
			
			print '</section>' # END interface
			
		done
		
		print "</section>" # END module
	done
	
	print "<footer>`htmlspecialchars_args "$footer"`</footer>"
}

export LANG=C

genDocs "$1" "$2" "$3"

# vim: ts=4 noet ai
